<!DOCTYPE html>
<html lang="en">
  <head>
    
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>


<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />



  <meta name="description" content="springMVC学习记录（二）基于代码的servlet容器初始化"/>




  <meta name="keywords" content="springMVC," />




  <link rel="alternate" href="/atom.xml" title="imIce">




  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=2.4.x" />



<link rel="canonical" href="http://yoursite.com/2017/08/17/springMVC-2/"/>


<meta name="description" content="springMVC简介 springMVC是围绕一个DispatcherServlet来设计的，这个servlet会把请求分发给各个处理器，并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染等，支持文件上传。处理器是你的应用中注解了@Controller和@RequestMapping的类和方法，spring为处理器方法提供了多样灵活的配置。spring3.0以后提供了@Controlle">
<meta name="keywords" content="springMVC">
<meta property="og:type" content="article">
<meta property="og:title" content="springMVC学习记录（二）基于代码的servlet容器初始化">
<meta property="og:url" content="http://yoursite.com/2017/08/17/springMVC-2/index.html">
<meta property="og:site_name" content="imIce">
<meta property="og:description" content="springMVC简介 springMVC是围绕一个DispatcherServlet来设计的，这个servlet会把请求分发给各个处理器，并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染等，支持文件上传。处理器是你的应用中注解了@Controller和@RequestMapping的类和方法，spring为处理器方法提供了多样灵活的配置。spring3.0以后提供了@Controlle">
<meta property="og:locale" content="en">
<meta property="og:image" content="https://tuchuang001.com/images/2017/08/01/figure-21-1-the-request-processing-workflow-in-spring-web-mv.jpg">
<meta property="og:updated_time" content="2017-10-12T02:23:34.754Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="springMVC学习记录（二）基于代码的servlet容器初始化">
<meta name="twitter:description" content="springMVC简介 springMVC是围绕一个DispatcherServlet来设计的，这个servlet会把请求分发给各个处理器，并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染等，支持文件上传。处理器是你的应用中注解了@Controller和@RequestMapping的类和方法，spring为处理器方法提供了多样灵活的配置。spring3.0以后提供了@Controlle">
<meta name="twitter:image" content="https://tuchuang001.com/images/2017/08/01/figure-21-1-the-request-processing-workflow-in-spring-web-mv.jpg">


<link rel="stylesheet" type="text/css" href="/css/style.css?v=2.4.x" />



  <link rel="stylesheet" type="text/css" href="/lib/fancybox/jquery.fancybox.css" />





<script>
  var CONFIG = {
    search: true,
    searchPath: "/search.xml",
    fancybox: true,
    toc: true,
  }
</script>




  



    <title> springMVC学习记录（二）基于代码的servlet容器初始化 · imIce </title>
  </head>

  <body><div id="mobile-navbar" class="mobile-navbar">
  <div class="mobile-header-logo">
    <a href="/." class="logo">imIce</a>
  </div>
  <div class="mobile-navbar-icon">
    <span></span>
    <span></span>
    <span></span>
  </div>
</div>

<nav id="mobile-menu" class="mobile-menu slideout-menu">
  <ul class="mobile-menu-list">
    
      <a href="/">
        <li class="mobile-menu-item">
          
          
            Home
          
        </li>
      </a>
    
      <a href="/archives/">
        <li class="mobile-menu-item">
          
          
            Archives
          
        </li>
      </a>
    
      <a href="/tags">
        <li class="mobile-menu-item">
          
          
            Tags
          
        </li>
      </a>
    
      <a href="/about">
        <li class="mobile-menu-item">
          
          
            About
          
        </li>
      </a>
    
  </ul>
</nav>

    <div class="container" id="mobile-panel">
      <header id="header" class="header"><div class="logo-wrapper">
  <a href="/." class="logo">imIce</a>
</div>

<nav class="site-navbar">
  
    <ul id="menu" class="menu">
      
        <li class="menu-item">
          <a class="menu-item-link" href="/">
            
            
              Home
            
          </a>
        </li>
      
        <li class="menu-item">
          <a class="menu-item-link" href="/archives/">
            
            
              Archives
            
          </a>
        </li>
      
        <li class="menu-item">
          <a class="menu-item-link" href="/tags">
            
            
              Tags
            
          </a>
        </li>
      
        <li class="menu-item">
          <a class="menu-item-link" href="/about">
            
            
              About
            
          </a>
        </li>
      
      
        <li class="menu-search">
          <form>
            <i class="iconfont icon-search" id="open-search"></i>
            <input type="text" class="search-input" id="search-input" />
            <i class="iconfont icon-close" id="close-search"></i>
          </form>
        </li>
      
    </ul>
  
</nav>

      </header>

      <main id="main" class="main">
        <div class="content-wrapper">
          <div id="content" class="content">
            
  
  <article class="post">
    <header class="post-header">
      <h1 class="post-title">
        
          springMVC学习记录（二）基于代码的servlet容器初始化
        
      </h1>

      <div class="post-meta">
        <span class="post-time">
          Aug 17, 2017
        </span>
      </div>
    </header>

    
    

    <div class="post-content">
      
        <p><strong>springMVC简介</strong></p>
<p>springMVC是围绕一个<code>DispatcherServlet</code>来设计的，这个servlet会把请求分发给各个处理器，并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染等，支持文件上传。处理器是你的应用中注解了<code>@Controller</code>和<code>@RequestMapping</code>的类和方法，spring为处理器方法提供了多样灵活的配置。spring3.0以后提供了<code>@Controller</code>注解机制，<code>@PathVariable</code>注解以及一些其他的特性，你可以使用它们来进行<code>RESTful</code> web站点和应用的开发。</p>
<a id="more"></a>
<blockquote>
<p><code>对扩展开发</code>是spring web MVC框架的一个重要的设计原则，对整个spring框架来说，设计原则就是传说中的 <code>对扩展开放，对修改关闭</code>。（OCP：Open-Closed Principle）<br>到底是啥意思呢，就是在设计一个软件系统模块（类，方法）的时候，应该可以在不修改原有的模块（修改关闭）的基础上，能扩展其功能（扩展开放）。</p>
<ul>
<li>扩展开放：某模块的功能是可扩展的，则该模块是扩展开放的，软件系统的功能上的<code>可扩展性</code>要求模块是扩展开放的。</li>
<li>修改关闭：某模块被其他模块调用，如果该模块的源代码不允许修改，则该模块修改关闭的。软件系统的功能上的<code>稳定性</code>，持续性要求是修改关闭的。</li>
</ul>
</blockquote>
<p><strong>DispatcherServlet</strong><br>spring MVC框架与其他很多web的MVC框架一样，请求驱动，所有设计都围绕着一个中央Servlet来展开，它负责把所有请求分发到控制器，同时提供其他Web应用开发所需要的功能。不过spring的中央处理器<code>DispatcherServlet</code>能做的比这更多。它与spring IOC容器做到了无缝集成，这意味着Spring提供的任何特性，在spring MVC中你都可以使用。</p>
<p><img src="https://tuchuang001.com/images/2017/08/01/figure-21-1-the-request-processing-workflow-in-spring-web-mv.jpg" alt=""></p>
<blockquote>
<p>这张图展示了Spring Web MVC的<code>DispatcherServlet</code>处理请求的工作流。熟悉设计模式的朋友会发现，DispatcherServlet应用的其实就是一个<code>前端控制器</code>的设计模式（其他很多优秀的web框架也都使用了这个设计模式）。</p>
</blockquote>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="comment">&lt;!--配置springMVC,这里的servlet名称决定着SpringMVC配置文件的名称--&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">servlet</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>spring-mvc<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">servlet-class</span>&gt;</span>org.springframework.web.servlet.DispatcherServlet<span class="tag">&lt;/<span class="name">servlet-class</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">init-param</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>contextConfigLocation<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>classpath:spring-mvc.xml<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></div><div class="line">  <span class="tag">&lt;/<span class="name">init-param</span>&gt;</span></div><div class="line">  <span class="comment">&lt;!--启动时加载,1代表优先级,越小代表越高--&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">load-on-startup</span>&gt;</span>1<span class="tag">&lt;/<span class="name">load-on-startup</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">servlet</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">servlet-mapping</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>spring-mvc<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></div><div class="line">  <span class="comment">&lt;!--这里修改为全部页面--&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>/<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">servlet-mapping</span>&gt;</span></div></pre></td></tr></table></figure>
<p>上一篇环境配置中我们使用的是 在web.xml 文件中配置<code>DispatcherServlet</code>的方法，标准的java-EE Servlet配置，所有请求都会被名字为spring-mvc的<code>DispatcherServlet</code>处理。<br>接下来我们使用基于代码配置的方法，需要在servlet 3.0环境下，我们引入<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="comment">&lt;!-- 导入java ee jar 包 --&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>javax<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>javaee-api<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">version</span>&gt;</span>7.0<span class="tag">&lt;/<span class="name">version</span>&gt;</span></div><div class="line">  <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></div></pre></td></tr></table></figure></p>
<p>MyWebApplicationInitializer.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyWebApplicationInitializer</span> <span class="keyword">implements</span> <span class="title">WebApplicationInitializer</span></span>&#123;</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onStartup</span><span class="params">(javax.servlet.ServletContext servletContext)</span> <span class="keyword">throws</span> ServletException </span>&#123;</div><div class="line"></div><div class="line">        XmlWebApplicationContext appConttext = <span class="keyword">new</span> XmlWebApplicationContext();</div><div class="line">        appConttext.setConfigLocation(<span class="string">"classpath:spring-mvc.xml"</span>);</div><div class="line"></div><div class="line">        ServletRegistration.Dynamic registration = servletContext.addServlet(<span class="string">"spring-mvc"</span>,<span class="keyword">new</span> DispatcherServlet(appConttext));</div><div class="line">        registration.setLoadOnStartup(<span class="number">1</span>);</div><div class="line">        registration.addMapping(<span class="string">"/"</span>);</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>这个例子和上面的<code>web.xml</code>配置文件是等效的<br><code>WebApplicationInitializer</code>是spring MVC提供的一个接口，它会查找你所有基于代码的配置，并应用它们来初始化Servlet 3.0版本以上的web容器，它有一个抽象的实现<code>AbstractDispatcherServletInitializer</code>,用以简化<code>DispatcherServlet</code>的注册工作，你只需要指定其servlet映射(mapping)即可。</p>
<p><strong>DispatcherServlet的处理流程</strong></p>
<p>配置好<code>DispatcherServlet</code>以后，开始有请求会经过这个DispatcherServlet，此时DispatcherServlet会按照以下次序对请求进行处理</p>
<blockquote>
<ul>
<li>首先搜索应用的上下文对象，WebApplicationContext并把它作为一个属性（attribute）绑定到该请求上，以便控制器和其他组件能够使用它。属性的键名默认为<code>DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE</code></li>
<li>将地区（locale）解析器绑定到请求上，以便其他组件在处理请求（渲染视图、准备数据等）时可以获取区域相关的信息。如果你的应用不需要解析区域相关的信息，忽略它即可</li>
<li>将主题（theme）解析器绑定到请求上，以便其他组件（比如视图等）能够了解要渲染哪个主题文件。同样，如果你不需要使用主题相关的特性，忽略它即可</li>
<li>如果你配置了multipart文件处理器，那么框架将查找该文件是不是multipart（分为多个部分连续上传）的。若是，则将该请求包装成一个<code>MultipartHttpServletRequest</code>对象，以便处理链中的其他组件对它做进一步的处理。</li>
<li>为该请求查找一个合适的处理器。如果可以找到对应的处理器，则与该处理器关联的整条执行链（前处理器，后处理器，控制器等）都会被执行，以完成相应模型的准备或视图的渲染</li>
<li>如果处理器返回的是一个模型（model），那么框架将渲染相应的视图。若没有返回任何模型（可能是因为前后的处理器出于某种原因拦截了请求等，比如安全问题），则框架不会渲染任何视图，此时认为对请求的处理可能已经由处理链完成了</li>
</ul>
</blockquote>
<p>如果在处理请求的过程中抛出了异常，那么上下文<code>WebApplicationContext</code>对象中所定义的异常处理器将会负责捕获这些异常。通过配置你自己的异常处理器，你可以定制自己处理异常的方式。</p>
<p>你可以定制DispatcherServlet的配置，具体的做法，是在web.xml文件中，Servlet的声明元素上添加一些Servlet的初始化参数（通过init-param元素）。该元素可选的参数列表</p>
<blockquote>
<ul>
<li><code>contextClass</code>   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;任意实现了WebApplicationContext接口的类。这个类会初始化该servlet所需要用到的上下文对象。默认情况下，框架会使用一个XmlWebApplicationContext对象。</li>
<li><code>contextConfigLocation</code>   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一个指定了上下文配置文件路径的字符串，该值会被传入给contextClass所指定的上下文实例对象。该字符串内可以包含多个字符串，字符串之间以逗号分隔，以此支持你进行多个上下文的配置。在多个上下文中重复定义的bean，以最后加载的bean定义为准</li>
<li><code>namespace</code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WebApplicationContext的命名空间。默认是[servlet-name]-servlet</li>
</ul>
</blockquote>

      
    </div>

    
      
      



      
      
  <div class="post-reward">
    <input type="checkbox" name="reward" id="reward" hidden />
    <label class="reward-button" for="reward">Reward</label>
    <div class="qr-code">
      
      
        <label class="qr-code-image" for="reward">
          <img class="image" src="/image/reward/wechat.png" title="wechat">
        </label>
      
      
        <label class="qr-code-image" for="reward">
          <img class="image" src="/image/reward/alipay.png" title="alipay">
        </label>
      
    </div>
  </div>

    

    
      <footer class="post-footer">
        
          <div class="post-tags">
            
              <a href="/tags/springMVC/">springMVC</a>
            
          </div>
        
        
        
  <nav class="post-nav">
    
      <a class="prev" href="/2017/08/17/slideLoading/">
        <i class="iconfont icon-left"></i>
        <span class="prev-text nav-default">手机端页面下滑异步加载数据</span>
        <span class="prev-text nav-mobile">Prev</span>
      </a>
    
    
      <a class="next" href="/2017/08/17/springMVC-1/">
        <span class="next-text nav-default">springMVC学习记录（一）环境搭建</span>
        <span class="prev-text nav-mobile">Next</span>
        <i class="iconfont icon-right"></i>
      </a>
    
  </nav>

      </footer>
    

  </article>


          </div>
          
  <div class="comments" id="comments">
    
  </div>


        </div>  
      </main>

      <footer id="footer" class="footer">

  <div class="social-links">
    
      
        
          <a href="mailto:ice105ow@qq.com" class="iconfont icon-email" title="email"></a>
        
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
    
    
      <a href="/atom.xml" class="iconfont icon-rss" title="rss"></a>
    
  </div>


<div class="copyright">
  <span class="power-by">
    Powered by <a class="hexo-link" href="https://hexo.io/">Hexo</a>
  </span>
  
  <span class="theme-info">
    Theme - 
    <a class="theme-link" href="https://github.com/ahonn/hexo-theme-even">Even</a>
  </span>

  <span class="copyright-year">
    
    &copy; 
     
      2016 - 
    
    2017

    <span class="heart">
      <i class="iconfont icon-heart"></i>
    </span>
    <span class="author">ice</span>
  </span>
</div>
      </footer>

      <div class="back-to-top" id="back-to-top">
        <i class="iconfont icon-up"></i>
      </div>
    </div>

    
  



    
  





  
    <script type="text/javascript" src="/lib/jquery/jquery-3.1.1.min.js"></script>
  

  
    <script type="text/javascript" src="/lib/slideout/slideout.js"></script>
  

  
    <script type="text/javascript" src="/lib/fancybox/jquery.fancybox.pack.js"></script>
  


    <script type="text/javascript" src="/js/src/even.js?v=2.4.x"></script>
<script type="text/javascript" src="/js/src/bootstrap.js?v=2.4.x"></script>

    
  <script type="text/html" id="search-result">
    <article class="post">
      <header class="post-header">
        <h1 class="post-title">
          <a href="$url$" class="post-link">
            $title$
          </a>
        </h1>
      </header>
      <div class="post-content">
        $content$
        <div class="read-more">
          <a href="$url$" class="read-more-link">
            Read more..
          </a>
        </div>
      </div>
    </article>
  </script>
  <script type="text/html" id="no-search-result">
    <div class="no-result">
      <h2>No result found!</h2>
    </div>
  </script>
  <script type="text/javascript" src="/js/src/search.js?v=2.4.x"></script>

  </body>
</html>
